package com.sniper.soap;

import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 采用php作为中间件，链接远程服务器
 * 提交方式可以采用GET|POST都可以
 *
 * @author suzhen
 * @create 2017/11/18
 */
public class PhpSoapClient {

    /**
     * 请求WSDL路径
     */
    private String wsdl = "http://api.wxfenxiao.com/Api/wsdl";

    /**
     * 请求参数
     */
    private String phpUrl = "http://www.misscorbu.com/soap/CallSoap.php?key=douwei800613";
    /**
     * 请求方法
     */
    private String methodName = "debugTest";

    /**
     * 客户端秘钥
     */
    private String secret = "e97abffdbf77626a83a076a948b178d1";

    /**
     * 请求参数
     */
    private Map<String, String> params = new LinkedHashMap<>();

    private static PhpSoapClient phpSoapClient = new PhpSoapClient();

    private PhpSoapClient() {
    }

    /**
     * 单例模式
     *
     * @return
     */
    public static PhpSoapClient getInstance() {
        return phpSoapClient;
    }

    /**
     * 设置请求的路径
     *
     * @param wsdl
     * @return
     */
    public PhpSoapClient withWsdl(String wsdl) {
        this.wsdl = wsdl;
        return this;
    }

    /**
     * 修改调用方法名字
     *
     * @param method
     * @return
     */
    public PhpSoapClient withMethod(String method) {
        this.methodName = method;
        return this;
    }

    /**
     * 修改客户端secret
     *
     * @param secret
     * @return
     */
    public PhpSoapClient withSecret(String secret) {
        this.secret = secret;
        return this;
    }

    /**
     * 传递请求参数
     *
     * @param params
     * @return
     */
    public PhpSoapClient withParams(Map<String, String> params) {
        this.params = params;
        return this;
    }


    /**
     * 根据key排序
     */
    class MapKeyComparator implements Comparator<String> {
        @Override
        public int compare(String str1, String str2) {
            return str1.compareTo(str2);
        }
    }

    /**
     * 使用 Map按key进行排序
     *
     * @param map
     * @return
     */
    private Map<String, String> sortMapByKey(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap<>(new MapKeyComparator());
        sortMap.putAll(map);
        return sortMap;
    }

    /**
     * 获取签名
     *
     * @return
     */
    private String getSign(Map<String, String> map) {
        Map<String, String> resultMap = sortMapByKey(map);
        StringBuilder stringBuffer = new StringBuilder();
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {
            stringBuffer.append(entry.getKey());
            stringBuffer.append(entry.getValue());
        }
        return DigestUtils.md5Hex(secret + stringBuffer.toString() + secret).toUpperCase();
    }


    /**
     * 执行请求
     *
     * @return
     */
    public String call() {
        Map<String, String> postData = new LinkedHashMap<>(params.size() + 3);
        postData.put("wsdl", this.wsdl);
        postData.put("method", this.methodName);
        Map<String, String> map = sortMapByKey(this.params);
        postData.putAll(map);
        postData.put("sign", getSign(map));

        return HttpUtil.httpPost(phpUrl, postData);
    }

    public static void main(String[] args) {
        PhpSoapClient phpSoapClient = PhpSoapClient.getInstance();
        Map<String, String> params = new LinkedHashMap<>();
        params.put("shop_id", "8001985");
        params.put("app_key", "2110406");
        String call = phpSoapClient
                .withMethod("getUsersLists")
                .withParams(params)
                .call();
        Map callResult = JSON.parseObject(call, Map.class);
        System.out.println(callResult);

    }
}
